package com.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.reggie.common.R;
import com.reggie.entity.Employee;
import com.reggie.mapper.EmployeeMapper;
import com.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.List;


@Slf4j
@RestController//restful风格
@RequestMapping("/employee")//请求路径
public class EmployeeController {
    @Autowired
    private EmployeeService employeeService;

    /**
     * 员工登录方法
     * @param request
     * @param employee
     * @return
     */
    //http://localhost:8080/employee/login
    @PostMapping("/login")            //传回来的JSON数据用实体类接收 所以使用@RequestBody注解
    public R<Employee> login(HttpServletRequest request, @RequestBody Employee employee) {
        /**1.将页面提交的密码password进行md5加密处理,得到加密后的字符串*/
        //提交的密码是在请求的json过来的,然后再打形参接收被封装在了实体employee中
        String password = employee.getPassword();//通过get密码的方法获取出来
        //使用加密工具类进行加密 这个加密方法需要字节类型 所以把字符串用getBytes方法转
        password = DigestUtils.md5DigestAsHex(password.getBytes());

        /**2.根据页面提交的用户名username查询数据库中员工数据信息*/
        //也就是使用byname的这种条件查找方法 选择使用Lambda表达式条件查询
        LambdaQueryWrapper<Employee> lqw = new LambdaQueryWrapper<>();
        //判断条件相等 就是提交的用户名和数据库中查询中查询的用户名相等 eq()相等
        lqw.eq(Employee::getUsername,employee.getUsername());

        /**3.如果没有查询到 则返回登录失败结果*/
        //没有查询到 就说明查到的是null 没有对应的对象
        //使用服务层接口查询 获得单个满足这样条件的数据对象
        Employee empone = employeeService.getOne(lqw);
        if(empone == null){
            //返回失败结果msg
            return R.error("登录失败,该用户不存在!");
        }

        /**4.密码比对 如果不一致 则返回登录失败结果*/
        //数据库里面存的密码也是md5加密后的结果
        if(!password.equals(empone.getPassword())){
            //返回失败结果
            return R.error("登录失败,密码错误!");
        }

        /**5.查看员工状态 如果为已禁用状态 则返回员工已禁用结果*/
        if(empone.getStatus() == 0){
            return R.error("登录失败,用户已被禁用!");
        }

        /**6.登录成功 放回成功消息该数据对象 并将员工id存入Session*/
        //从请求中获取Session 然后set键值对中键对应的值
        //这个session的键名自己设置一个合适的
        request.getSession().setAttribute("employee",empone.getId());
        return R.success(empone);
    }


    /**
     * 员工退出
     * @param request
     * @return
     */
    //http://localhost:8080/employee/logout
    @PostMapping("/logout")//表单没提交什么东西过来 所以不用接什么数据
    public R<String> logout(HttpServletRequest request){
        /**清理Session中的用户id*/
        //跳转啥的不归后端管 是前端管的
        //我们在登录的时候设置了 登录成功之后把id放到Session里面 现在我们推出的话就是要清理这个
        //我们当时定义的id的Session中的属性名为employee 把这个属性名的东西直接干掉就可以了
        request.getSession().removeAttribute("employee");
        //这时候不返回数据了 直接返回消息
        return R.success("退出登录成功!");
    }


    /**
     * 新增员工(zg)
     * @param request
     * @param employee
     * @return
     */
    @PostMapping()
    public R<String> empSave(HttpServletRequest request,@RequestBody Employee employee){
        log.info("新增员工，员工信息：{}",employee.toString());
        //提交的表单信息全部在@RequestBody employee中
        /**1.新增员工时 MD5加密初始密码*/
        String password = DigestUtils.md5DigestAsHex("123456".getBytes());
        employee.setPassword(password);
        /**2.封装时间 修改时间 创建人 修改人信息 (从session中获取当前登录用户)*/
        //先从session中获取employee的字段id 就是当前用户的id
        //Long empId = (Long) request.getSession().getAttribute("employee");

        //封装时间 创建时间 修改时间
        //LocalDateTime localDateTime = LocalDateTime.now();
        //employee.setCreateTime(localDateTime);
        //employee.setUpdateTime(localDateTime);

        //创建人 修改人信息
        //employee.setCreateUser(empId);
        //employee.setUpdateUser(empId);

        /**3.把employee存入数据库*/
        employeeService.save(employee);
        //在这里进行保存的时候 因为数据库中的索引指定用户名为唯一的 如果提交了一个相同的新增员工用户名出来
        //就会抛出异常SQLIntegrityConstraintViolationException
        //但是每次都try catch来捕获异常未免太冗杂了 所以可以使用全局异常捕捉的方式

        //返回成功消息
        return R.success("新增员工成功!");
    }

    /**
     * 员工分页查询
     */
    @GetMapping("/page")
    public R<Page> empPagepSelect( int page, int pageSize, String name){
        /**A. 构造分页条件*/
        //前端需要获取 total总条数 和 records当前页数据
        Page pageInfo = new Page(page,pageSize);//pageInfo页码信息
        LambdaQueryWrapper<Employee> lqw = new LambdaQueryWrapper<>();
        /**B. 构建搜索条件 - name进行模糊匹配*/
//        if(name!=null){
//            lqw.likeLeft(Employee::getName,name);
//        }
        //添加过滤条件 第一个参数为true时才会进行条件查询
        lqw.like(StringUtils.isNotEmpty(name),Employee::getName,name);
        /**C. 构建排序条件 - 更新时间倒序排序*/
        lqw.orderByDesc(Employee::getUpdateTime);

        /**D. 执行查询*/
        employeeService.page(pageInfo, lqw);

        /**E. 组装结果并返回*/
        return R.success(pageInfo);

    }

    /**
     * 员工启用禁用功能
     */
    @PutMapping()
    public R<String> EnableAndDisableUpdate(HttpServletRequest request,@RequestBody Employee employee){
        log.info(employee.toString());
        //启用、禁用员工账号，本质上就是一个更新操作，也就是对status状态字段进行操作。
        //在Controller中创建update方法，此方法是一个通用的修改员工信息的方法。
        //发过来的RequestBody包含了要启用禁用的员工id 以及将要更改的状态1或0
        /**1.获取当前操作的用户id 用于后面更新操作者 从session中获取*/
        Long empId = (Long) request.getSession().getAttribute("employee");

        //2.更新员工信息
        //employee.setUpdateTime(LocalDateTime.now());
        //employee.setUpdateUser(empId);

        //3.修改数据库中数据
        employeeService.updateById(employee);
        return R.success("更新员工信息成功!");
    }

    /**
     * 员工信息编辑查询回显
     * @return
     */
    @GetMapping("/{id}")
    public R<Employee> selectOneEmployee(@PathVariable Long id){//前面不用注解是因为"?"已经告知是参数了
        //后端查到这个id的对象之后把它返回给前端
        LambdaQueryWrapper<Employee> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Employee::getId,id);
        Employee employeeOne = employeeService.getOne(lqw);
        //判断是否查到了
        if(employeeOne != null){
            return R.success(employeeOne);
        }
        return R.error("没有查到该员工!");
    }



}
